package icbc.nav.control
{
	import com.greensock.TweenLite;
	import com.greensock.easing.Strong;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.DropShadowFilter;
	import flash.geom.Point;
	
	import icbc.app.control.Alert;
	import icbc.nav.Session;
	import icbc.nav.entity.Menu;
	import icbc.nav.entity.MenuChild;
	import icbc.nav.event.MenuContentEvent;
	import icbc.nav.view.ContentView;
	
	import org.osflash.signals.Signal;
	
	public class MenuListControl extends Sprite
	{
		public static const EVENT_CLOSE:String = "menuControl.Close";
		private static const MAX_MENU_HEIGHT:int = (11*26);
		protected var panel:Sprite;
		protected var modal:Sprite;
		public var viewWidth:uint;
		public var viewHeight:uint;
		private var menuData:MenuChild;
		private var menuItemWidth:uint = 200;
		private var menuItemHeight:uint = 26;
		private var rounded:uint = 10;
		private var parentPoint:Point;
		private var initialPosy:int = 0;
		private var gapXInterMenu:uint = 5;
		private var remainingMenu:Array;
		public var onOpenLevel:Signal = new Signal();
		public var onCloseLevel:Signal = new Signal();
		public var onContentOpened:Signal = new Signal(MenuChild);
		private var menuSpace:Sprite;
		private var maskMenu:Sprite;
		private var upButton:UpDownButton;
		private var downButton:UpDownButton;
		
		public function MenuListControl(menuData:MenuChild, parentPoint:Point, remainingMenu:Array = null)
		{
			super();
			this.parentPoint = parentPoint;
			this.menuData = menuData;
			this.menuItemWidth = menuData.childWidth > 0 ? menuData.childWidth : menuItemWidth;
			this.remainingMenu = remainingMenu;
			addEventListener(Event.ADDED_TO_STAGE, initStage);
		}

		private function initStage(evt:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, initStage);
			initContent();
		}
		
		private function initContent():void
		{
			buildModal();
			panel = setBasePanel();
			addChild(panel);
			panel.x = parentPoint.x;
			panel.y = parentPoint.y;
			panel.alpha = 0;
			
			menuSpace = new Sprite();
			panel.addChild(menuSpace);
			
			maskMenu = buildMaskMenu();
			panel.addChild(maskMenu);
			
			setMenuChild();
			
			if(panel.y+menuSpace.height > stage.stageHeight)
			{
				panel.y = stage.stageHeight - menuSpace.height - 90;
				if(panel.y < 0) panel.y = 20;
			}
			initialPosy = panel.y;
			showMenuList();
		}

		private function hideMenuList():void
		{
			closeView();
		}
		
		private function showMenuList():void
		{
			var tween:TweenLite = new TweenLite(panel,0.5,{ease:Strong.easeOut, y:initialPosy, alpha:1, onComplete:function():void{ addPanelListener(); }});
		}

		private function buildModal():void
		{
			modal = new Sprite();
			modal.graphics.beginFill(0x000000,0);
			modal.graphics.drawRect(0,0, stage.stageWidth, stage.stageHeight);
			modal.graphics.endFill();
			addChild(modal);
		}
		
		private function addPanelListener():void
		{
			modal.addEventListener(MouseEvent.CLICK, modalClickHandler);
			return;

			var overFnc:Function;
			panel.addEventListener(MouseEvent.MOUSE_OVER, overFnc = function(evt:MouseEvent):void{
				panel.removeEventListener(MouseEvent.MOUSE_OVER, overFnc);
				addModalListener();
			});
		}
		
		private function modalClickHandler(evt:MouseEvent):void
		{
			closeControl();
		}
		
		public function closeControl():void
		{
			removeModalListener();
			removeChild(modal);
			hideMenuList();
		}
		
		private function closeChildren():void
		{
			for(var i:uint = 0; i<numChildren; i++)
			{
				if(getChildAt(i) is MenuListControl)
				{
					var item:MenuListControl = getChildAt(i) as MenuListControl;
					item.closeControl();
				}
			}
		}
		
		private function addModalListener():void
		{
			modal.addEventListener(MouseEvent.MOUSE_OVER, modalClickHandler);
		}

		private function removeModalListener():void
		{
			modal.removeEventListener(MouseEvent.MOUSE_OVER, modalClickHandler);
			modal.removeEventListener(MouseEvent.CLICK, modalClickHandler);
		}

		protected function setBasePanel():Sprite
		{
			viewWidth = menuItemWidth;
			viewHeight = (menuData.childs.length * menuItemHeight);
			viewHeight = viewHeight > MAX_MENU_HEIGHT ? MAX_MENU_HEIGHT : viewHeight;
			return buildPlainPanel();
		}

		protected function buildPlainPanel():Sprite
		{
			var base:Sprite = new Sprite();
			base.graphics.beginFill(0x000000,0);
			base.graphics.drawRect(0, 0, viewWidth, viewHeight);
			base.graphics.endFill();
			return base;
		}
		
		private function closeView():void
		{
			dispatchEvent(new Event(EVENT_CLOSE));
		}
		
		private function setMenuChild():void
		{
			var posx:uint = 0;
			var posy:uint = 0;
			var idx:uint = 0;
			for each(var menuChild:MenuChild in menuData.childs)
			{
				var buttonType:uint = idx > 0 ? MenuButton.TYPE_MIDDLE : MenuButton.TYPE_UP;
				if(idx == menuData.childs.length-1)
				{
					buttonType = MenuButton.TYPE_BOTTOM;
				}
				var item:MenuButton = new MenuButton({label:menuChild.name, source:menuChild}, menuItemWidth, menuItemHeight, MenuButton.STYLE_CHILD, buttonType);
				item.addEventListener(MenuButton.EVENT_CLICK, menuItemClick);
				
				menuSpace.addChild(item);

				item.x = posx;
				item.y = posy; posy += item.height;
				idx++;
			}
			setMaskMenu();
		}
		
		private function setMaskMenu():void
		{
			maskMenu.mouseEnabled = false;
			maskMenu.mouseChildren = false;
			if(menuSpace.height > MAX_MENU_HEIGHT)
			{
				menuSpace.mask = maskMenu;
				setMaskMode();
			}
		}
		
		private function buildMaskMenu():Sprite
		{
			var sprite:Sprite = new Sprite();
			sprite.graphics.beginFill(0x000000,0);
			sprite.graphics.drawRect(0,0, viewWidth+1, MAX_MENU_HEIGHT);
			sprite.graphics.endFill();
			return sprite;
		}

		private function menuItemClick(evt:Event):void
		{
			clearStates();
			var menuButton:MenuButton = evt.target as MenuButton;
			openMenu(menuButton, remainingMenu);
		}

		private function openMenu(menuButton:MenuButton, remainingMenu:Array):void
		{
			var menuChild:MenuChild = menuButton.data.source;
			if(menuChild.type == MenuChild.TYPE_CONTENT)
			{
				openContent(menuChild);
				onContentOpened.dispatch(menuData);
				return;
			}
			if(menuChild.childs.length == 0) return;

			var parentPoint:Point = new Point(panel.x+menuButton.width+gapXInterMenu, panel.y+menuButton.y-10);
			
			var menuList:MenuListControl = new MenuListControl(menuChild, parentPoint, remainingMenu);
			menuList.addEventListener(MenuListControl.EVENT_CLOSE, closeMenuHandler);
			menuList.onOpenLevel.add(openLevelHandler);
			menuList.onCloseLevel.add(closeLevelHandler);
			addChild(menuList);
			onOpenLevel.dispatch();

			if(remainingMenu.length > 0)
			{
				var menuName:String = remainingMenu[0];
				remainingMenu.reverse();
				remainingMenu.pop();
				remainingMenu.reverse();
				navigateTo(menuName, remainingMenu);
			}
		}

		private function openLevelHandler():void
		{
			onOpenLevel.dispatch();
		}

		private function closeLevelHandler():void
		{
			onCloseLevel.dispatch();
		}

		private function closeMenuHandler(evt:Event):void
		{
			var menuList:MenuListControl = evt.target as MenuListControl;
			menuList.removeEventListener(MenuListControl.EVENT_CLOSE, closeMenuHandler);

			clearStates();
			onCloseLevel.dispatch();
			removeChild(menuList);
		}
		
		private function clearStates():void
		{
			var parentMenu:Sprite = menuSpace;
			for(var i:uint = 0; i<parentMenu.numChildren; i++)
			{
				if(parentMenu.getChildAt(i) is MenuButton)
				{
					var item:MenuButton = parentMenu.getChildAt(i) as MenuButton;
					item.clearState();
				}
			}
		}
		
		public function addListener():void
		{
			addModalListener();
		}

		public function removeListener():void
		{
			removeModalListener();
		}
		
		private function openContent(menuChild:MenuChild):void
		{
			dispatchEvent(new MenuContentEvent(MenuContentEvent.OPEN, menuChild, true));
		}
		
		public function navigateTo(menuName:String, fullPath:Array):void
		{
			var parentMenu:Sprite = menuSpace;
			var firstMenuName:String = fullPath[0];
			for(var i:uint = 0; i<parentMenu.numChildren; i++)
			{
				if(parentMenu.getChildAt(i) is MenuButton)
				{
					var item:MenuButton = parentMenu.getChildAt(i) as MenuButton;
					var menuChild:MenuChild = item.data.source;
					if(menuChild.name == firstMenuName)
					{
						fullPath.reverse();
						fullPath.pop();
						fullPath.reverse();
						openMenu(item, fullPath);
					}
				}
			}
		}
		
		private function setMaskMode():void
		{
			var updownHeight:int = 22;
			upButton = new UpDownButton({label:"Menos opciones"}, menuItemWidth, updownHeight, false);
			upButton.onClicked.add(updownClickHandler);
			panel.addChild(upButton);
			upButton.y = menuSpace.y - updownHeight;

			downButton = new UpDownButton({label:"Mas opciones"}, menuItemWidth, updownHeight, true);
			downButton.onClicked.add(updownClickHandler);
			panel.addChild(downButton);
			downButton.y = maskMenu.y+maskMenu.height;
		}
		
		private function updownClickHandler(menuButton:UpDownButton):void
		{
			var movex:int = 0;
			if(menuButton == upButton)
			{
				movex = menuItemHeight;
				if(menuSpace.y == 0)
				{
					movex = 0;
				}
			} else {
				movex = -menuItemHeight;
				if(menuSpace.y + menuSpace.height <= MAX_MENU_HEIGHT)
				{
					movex = 0;
				}
			}
			menuSpace.y += movex;
		}
	}
}